package uk.ac.sanger.dasregistry.timer;

import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import java.util.Timer;

import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.sql.DataSource;


import org.biojava.dasobert.dasregistry.DasSource;
import org.biojava.services.das.dao.DasSourceManager;
import org.biojava.services.das.registry.ConfigBean;
import org.biojava.services.das.registry.DasRegistrySql;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.logging.Logger;

public class Archiver implements Job {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	public static Logger logger =  Logger.getLogger("uk.ac.sanger.dasregistry.timer.Archiver");

	int contactParentFrequency;
	Timer timer;
	DasSourceManager dao;

	boolean showValidationLog = true;
	public static final int ONEHOUR = 1000 * 60 * 60 ;
	//public static final int ONEHOUR = 1000 * 60 ;
	
	/**
	 *  @params validationFrequency in milli-seconds
	 */
	public Archiver() {
		super();
		BeanFactory ctx=(new ClassPathXmlApplicationContext("SpringDAO.xml"));
		DasSourceManager dao=(DasSourceManager) ctx.getBean("dasSourceManager");
	}



	private void releaseArchivingLock(DasRegistrySql registry) {
		System.out.println("releasing Archiver lock");
		DataSource dataSource = registry.getDataSource();

		Connection conn = null ;
		//boolean doValidate = false;
		try {
			conn = dataSource.getConnection();
			dao.releaseAdminLock(conn,"archiving","lastArchive");
			//as we now update the valid_capabilities tables we want
			//to tell the sources.xml returned by the registry it will need updating etc
			dao.pingLastModified(conn);

		} catch (Exception e) { 
			e.printStackTrace();
		} finally {
			if ( conn != null) {
				try { 
					conn.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}	
	}




	

	/** send notification mails to admins of servers that have been down for > 2 days ...
	 * @param registry the registry worker
	 */
	public void sendDeletionNotificationMails(DasRegistrySql registry) {
		//disable email notifications here if testing
		registry.sendAdminDeletionNotificationMails();
		//also tell the sources cmd that the database has changed and so it needs to be regenerated
		
		
		//also need to check if source has been not valid for 1 or 2months and if so send final email
		//if not valid by 2 weeks after that final email delete the source and move to archive table
		
	}


	public void execute(JobExecutionContext arg0) throws JobExecutionException {


		//System.out.println("AutoValidation called");

		ApplicationContext context = new ClassPathXmlApplicationContext("config_dasregistry.xml");

		DasRegistrySql registry = (DasRegistrySql) context.getBean("registryBean");

		ConfigBean config = (ConfigBean) context.getBean("configBean");
		showValidationLog = config.isPrintValidationStatus();
		
		DataSource dataSource = registry.getDataSource();
		
		List<DasSource> sourcesForArchiving=null;
		
	

		Connection conn = null ;
		boolean doArchiving = false;
		try {
			conn = dataSource.getConnection();

			doArchiving = dao.doAdminChecks(conn, 
					"lastArchive" ,
					"archivingStarted" ,
					"archiving");
			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if ( conn != null ) {
				try {
					conn.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}

		//toggle out for debug as want to run anyway
		if ( ! doArchiving ) {
			logger.info(" not running archiving due to dao admin checks... ");
			return;
		}
System.out.println("runnning Archiving ---------------------------------------------------------------------------");
		

		
		

		// retrieve all DasSources from registry and try to validate them...
		try {
			sourcesForArchiving = registry.listServicesForArchiving();
			
			
			
			

			

		} catch ( Exception e){
			e.printStackTrace();
			logger.info("could not auto-validate das sources:" + e.getMessage());
		}

		System.out.println("number of set for archiving="+sourcesForArchiving.size());
	
		sendDeletionNotificationMails(registry);
		if(registry.archiveServers(sourcesForArchiving)){
			logger.info("successfully archived sources");//only archive after sending emails as otherwise we won't be able to get info on the servers	
		}else{
			logger.info("something went wrong when archiving a server - mayvbe in archive database already?");
		}

		releaseArchivingLock(registry);
		
		
		registry = null;

	
		
	}


}
